import Flutter
import UIKit




public class SwiftBlePrinterPlugin: NSObject, FlutterPlugin {
    
    public static func register(with registrar: FlutterPluginRegistrar) {
        let channel = FlutterMethodChannel(name: "com.kayoxu.plugin.ble_printer", binaryMessenger: registrar.messenger())
        let instance = SwiftBlePrinterPlugin()
        registrar.addMethodCallDelegate(instance, channel: channel)
        FlutterEventPlugin.share.registerWithRegistry(messenger: registrar.messenger())
        FlutterEventHomePlugin.share.registerWithRegistry(messenger: registrar.messenger())
        FlutterEventBlePlugin.share.registerWithRegistry(messenger: registrar.messenger())
    }
    
    public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
        let manager = JWBluetoothManage.sharedInstance()
        switch call.method {
        case "bleInit":
            if manager!.stage != .characteristics {
                if UserDefaults.standard.string(forKey: "BluetoothPeripheral_uuid") == nil {
                    result(-1)
                }else{
//                    manager?.autoConnectLastPeripheralCompletion({ peripheral, err in
//                        if (err == nil) {
//                            DispatchQueue.global().asyncAfter(deadline: .now() + 0.2) {
//                                result(EventType.BLE_CONNECTED.rawValue)
//                            }
//                        }else{
//                            result(EventType.BLE_CONNECTE_FAILED.rawValue)
//                        }
//                    })

                    let uuidStr = UserDefaults.standard.string(forKey: "BluetoothPeripheral_uuid") ?? ""
                    manager?.beginScanPerpheralSuccess({ peripherals, rssis in
                        let deviceList:Array = peripherals!
                        for i in 0..<deviceList.count {
                            let cbp:CBPeripheral = deviceList[i]
                            let cbpU:String = cbp.identifier.uuidString
                            if (cbpU == uuidStr) {
                                manager?.connect(cbp, completion: { peripheral, err in
                                    if (err == nil) {
                                       DispatchQueue.global().asyncAfter(deadline: .now() + 0.2) {
                                         result(EventType.BLE_CONNECTED.rawValue)
                                     }
                                    }else{
                                        result(EventType.BLE_CONNECTE_FAILED.rawValue)
                                    }
                                })
                                manager?.stopScanPeripheral()
                                break
                            }
                        }
                        
                    }, failure: { err in
                        result(EventType.BLE_CONNECTE_FAILED.rawValue)
                    })
                }
            }else{
                result(EventType.BLE_CONNECTED.rawValue)
            }
            
        case "searchBle":
            manager?.beginScanPerpheralSuccess({ peripherals, rssis in
                let deviceList:Array = peripherals!
                let rssisList:Array = rssis!
                var bluetoothDevices:Array = Array<FlutterData.BleDevice>()
                for i in 0..<deviceList.count {
                    let cbp:CBPeripheral = deviceList[i]
                    bluetoothDevices.append(FlutterData.BleDevice.init(name: cbp.name, mac: cbp.identifier.uuidString, bound: 0))
                }
                FlutterDataUtils.share.sendEvent(type: EventType.BLE_FOUND.rawValue, data: bluetoothDevices)
            }, failure: { err in
                print(err)
            })
            result("")
        case "stopSearchBle":
            manager?.stopScanPeripheral()
        case "connectBle":
            let uuidStr = UserDefaults.standard.string(forKey: "BluetoothPeripheral_uuid") ?? ""
            let arguments:[String:Any] = call.arguments as! [String : Any]
            let argument:String = arguments["data"] as! String
            let bleDevice = JsonUtils.getEntity(FlutterData.BleDevice.self, obj: argument)
                manager?.beginScanPerpheralSuccess({ peripherals, rssis in
                    let deviceList:Array = peripherals!
                    for i in 0..<deviceList.count {
                        let cbp:CBPeripheral = deviceList[i]
                        let cbpU:String = cbp.identifier.uuidString
                        if (cbpU == bleDevice?.mac) {
                            manager?.connect(cbp, completion: { peripheral, err in
                                if (err == nil) {
                                    let l = EventType.BLE_CONNECTED.rawValue
                                    result(EventType.BLE_CONNECTED.rawValue)
                                    FlutterDataUtils.share.sendEvent(type: EventType.BLE_CONNECTED.rawValue, data: "");
                                }else{
                                    result(EventType.BLE_CONNECTE_FAILED.rawValue)
                                    FlutterDataUtils.share.sendEvent(type: EventType.BLE_CONNECTE_FAILED.rawValue, data: "");
                                }
                            })
                            manager?.stopScanPeripheral()
                            break
                        }
                    }
                    
                }, failure: { err in
                    result(EventType.BLE_CONNECTE_FAILED.rawValue)
                    FlutterDataUtils.share.sendEvent(type: EventType.BLE_CONNECTE_FAILED.rawValue, data: "");
                })

        case "printData":
            let arguments:[String:Any] = call.arguments as! [String : Any]
            let argument:String = arguments["data"] as! String
            let json:[FlutterData.PrinterTicketData] = JsonUtils.getEntityList(Array<FlutterData.PrinterTicketData>.self, obj: argument)!
            let pa = DispatchQueue(label: "serial")
            pa.sync {
                for data in json {
                    self.beginPrint(data: data)
                    sleep(5)
                }
            }
            
            
        default:
            break
        }
    }
    
    func sendEvent(params: String?) {
        if FlutterEventPlugin.share.eventSink != nil {
            FlutterEventPlugin.share.eventSink!(params)
        }
        if FlutterEventHomePlugin.share.eventSink != nil {
            FlutterEventHomePlugin.share.eventSink!(params)
        }
        if FlutterEventBlePlugin.share.eventSink != nil {
            FlutterEventBlePlugin.share.eventSink!(params)
        }
    }
    
    func beginPrint(data:FlutterData.PrinterTicketData) {
        let printer = JWPrinter()
        let img:UIImage = printer.setTopView(data.company)
        printer.append(img, alignment: .center, maxWidth: 160)
        printer.appendTitle("起点", value: "", bold: false)
        printer.appendSeperatorLine()
        printer.appendText(data.addressStart, alignment: .left, fontSize: .titleBigBig)
        printer.appendTitle("车牌号", value: "驾驶员", bold: false)
        printer.appendSeperatorLine()
        printer.appendTitle(data.carNum, value: data.driverName, fontSize: .titleBigBig, bold: true)
        printer.appendTitle("开单时间", value: "", bold: false)
        printer.appendSeperatorLine()
        printer.appendTitle(data.ticketTime, value: "", bold: true)
        printer.appendNewLine()
        printer.appendTitle("开单人", value: "", bold: false)
        printer.appendSeperatorLine()
        printer.appendTitle(data.ticketUser, value: "", bold: true)
        printer.appendNewLine()
        printer.appendTitle("终点", value: "", bold: false)
        printer.appendSeperatorLine()
        printer.appendTitle(data.addressEnd, value: "", bold: true)
        printer.appendNewLine()
        printer.appendTitle("运单号", value: "", bold: false)
        printer.appendSeperatorLine()
        printer.appendTitle(data.ticketId, value: "", bold: true)
        printer.appendNewLine()
        printer.appendTitle("当日趟次", value: "", bold: false)
        printer.appendSeperatorLine()
        printer.appendTitle(data.ticketTimes, value: "", bold: true)
        printer.appendNewLine()
        printer.appendBarCode(withInfo: data.ticketBarCode, alignment: .center, maxWidth: 300)
        printer.appendNewLine()
        printer.appendQRCode(withInfo: data.ticketQrCode, size: 3, alignment: .center)
        printer.appendNewLine()
        printer.appendSeperatorLine()
        let mainData = printer.getFinalData()
        JWBluetoothManage.sharedInstance().sendPrint(mainData) { completion, connectPerpheral, err in
            if completion {
                print("打印成功")
            }else{
                print(err!)
            }
        }
    }
    
}
